/*
 * TableroSDL.cpp
 *
 *  Created on: 23/10/2013
 *      Author: fernando
 */

#include "TableroSDL.h"
#include "Confite.h"
#include "Barrita.h"
#include "EstrellaDorada.h"
#include "resize++.h"
#include <iostream>
#include <stdlib.h>
#include <string>
#include <vector>

using std::string;
using std::vector;
using std::cout;
using std::endl;

const int SIZECELL = 64;
const int CANTPIXELS = 8;


TableroSDL::TableroSDL(int columns, int rows) {
	columnas = columns;
	filas = rows;
	ancho = columns * 64 + SIZEEXTRA;
	cout << rows <<endl;
	cout << columns <<endl;
	alto = rows * 64;
	fondo = NULL;
	explode = Mix_LoadWAV("Sonidos/missile.wav");
	dibujarJugadas = false;
}

TableroSDL::~TableroSDL() {
	SDL_FreeSurface(fondo);
	for (vector<CeldaSDL*>::iterator It = celdas.begin();
			It != celdas.end(); ++It){
		delete (*It);
	}
	for (vector<Puntaje*>::iterator It2 = puntajes.begin();
			It2 != puntajes.end(); ++It2){
		delete (*It2);
	}
	for (vector<Jugada*>::iterator It3 = jugadas.begin();
			It3 != jugadas.end(); ++It3){
		delete (*It3);
	}
	Mix_FreeChunk(explode);
}

int TableroSDL::dibujar(bool fin){
	SDL::apply_surface(0, 0, fondo, screen, NULL);
	if (!fin){
		for (vector<CeldaSDL*>::iterator It = celdas.begin();
						It != celdas.end(); ++It){
			(*It)->dibujar(screen, false);
		}
		for (vector<Puntaje*>::iterator It2 = puntajes.begin();
				It2 != puntajes.end(); ++It2){
			(*It2)->dibujar(screen);
		}
	}
	//Apply the images to the screen
	SDL_Flip(screen);
	return 0;
}

Golosina* TableroSDL::getGolosinaConPosicion(unsigned int x, unsigned int y){
	Golosina* golosina = NULL;
	CeldaSDL* cell = getCeldaFromPos(x,y);
	if (cell != NULL){
		golosina = cell->getGolosina();
	}
	return golosina;
}

CeldaSDL* TableroSDL::getCeldaFromPos(unsigned int x, unsigned int y){
	CeldaSDL* cell = NULL;
	int nCol, nFil, nCel;
	if (x < ancho && x >= 0 && y < alto && y >= 0){
		nCol = (x/64);
		nFil = (y/64);
		nCel = nCol*filas + nFil;
		cell = celdas[nCel];
	}
	return cell;
}

CeldaSDL* TableroSDL::getCelda(unsigned int pos){
	return celdas.at(pos);
}


void TableroSDL::setFondo(string fileName){
	SDL_FreeSurface(fondo);
	fondo  = load_image(fileName);
	if (fondo == NULL){
		fondo = load_image("Imagenes/fondo_default.jpg");
	}
	fondo = SDL_Resize(fondo, ancho, alto, true, 4);
}

unsigned int TableroSDL::getPosCorner(unsigned int pos){
	int aux = (pos/SIZECELL)*SIZECELL;
	if(aux == 0){
		aux = 1;
	}
	return aux;
}

unsigned int TableroSDL::getNumeroColumnas(){
	return columnas;
}

unsigned int TableroSDL::getNumeroFilas(){
	return filas;
}

unsigned int TableroSDL::getAncho(){
	return ancho;
}


void TableroSDL::createPuntajes(Json::Value value, unsigned int x){
	Puntaje* puntaje;
	int counter = 0;
	for(Json::Value::iterator it = value.begin(); it != value.end(); ++it){
		puntaje = new Puntaje((*it)["usuario"].asString());
		puntaje->setPosicion(x, counter*60 + 10);
		puntajes.push_back(puntaje);
		counter++;
	}
}

void TableroSDL::inicializarTablero(Json::Value tableroJson){
	unsigned int counter = 0;
	CeldaSDL* celda;
	init("Tablero");
	setFondo("Imagenes/" + tableroJson["fondo"].asString());
	unsigned int nroFila;
	unsigned int nroCol;
	unsigned int posX;
	unsigned int posY;
	for (Json::Value::iterator it = tableroJson["vector"].begin();
			it != tableroJson["vector"].end(); ++it) {
		bool vacia = (*it)["vacia"].asBool();
		nroFila = counter%getNumeroFilas();
		nroCol = counter/getNumeroFilas();
		posX = nroCol*SIZECELL;
		posY = nroFila*SIZECELL;
		celda = new CeldaSDL(!vacia,posX,posY ,counter);
		Golosina * gol;
		int color;
		int orientacion;
		if(!vacia){
			std::string pieza = (*it)["tipo"].asString();
			if (pieza == "minibar"){
				  color = (*it)["color"].asInt();
				  orientacion = (*it)["orientacion"].asInt();
				  gol = new Barrita(color,orientacion,posX,posY);
			} else if (pieza == "GoldenStar"){
				  gol = new EstrellaDorada(posX,posY);
			} else {
				  color = (*it)["color"].asInt();
				  gol = new Confite(color,posX,posY);
			}
			celda->setGolosina(gol);
		}
		celdas.push_back(celda);
		counter++;
	}
}


void TableroSDL::actualizarPuntajes(Json::Value values){
	for(Json::Value::iterator it = values.begin(); it != values.end(); ++it){
		for (vector<Puntaje*>::iterator itP = puntajes.begin();
				itP != puntajes.end(); ++itP){
			if (((*it)["usuario"].asString()).compare((*itP)->getJugador())
					== 0){
				(*itP)->setPuntos((*it)["puntos"].asInt());
			}
		}
	}
}

void TableroSDL::vaciarJugadas(){
	jugadas.clear();
	dibujarJugadas = false;
}

void TableroSDL::addJugada(Jugada* jug){
	jugadas.push_back(jug);
}

bool TableroSDL::hayJugadas(){
	return (!jugadas.empty());
}

void TableroSDL::dibujarSinFondo(){
	for (vector<Jugada*>::iterator It = jugadas.begin();
							It != jugadas.end(); ++It){
		vector<unsigned int> pos = (*It)->getPosEspeciales();
		vector<Golosina*> reemp = (*It)->getReemplazosEsp();
		int contador = 0;
		for (vector<unsigned int>::iterator esp = pos.begin();
									esp != pos.end(); ++esp){
			CeldaSDL* celda = getCelda(*esp);
			celda->dibujar(screen, true);
			Mix_PlayChannel(-1, explode, 0);
			celda->destruirContenido();
			celda->setGolosina(reemp.at(contador));
			contador++;
		}
		contador = 0;
		pos = (*It)->getPosComunes();
		reemp = (*It)->getReemplazosComunes();
		for (vector<unsigned int>::iterator esp = pos.begin();
									esp != pos.end(); ++esp){
			CeldaSDL* celda = getCelda(*esp);
			celda->dibujar(screen, true);
			Mix_PlayChannel(-1, explode, 0);
			celda->destruirContenido();
			if (((celda->getNumero())%(getNumeroFilas())) > 0){
				bajarGolosina(celda->getNumero() - 1);
			}
			reponerGolosina(reemp.at(contador),
								celda->getNumero()/getNumeroFilas());
			contador++;
		}
		dibujar(false);
	}
	vaciarJugadas();
}


void TableroSDL::bajarGolosina(unsigned int nCelda){
	unsigned int nCeldaAbajo = nCelda+1;
	CeldaSDL* celda;
	CeldaSDL* celdaAbajo;
	Golosina* golosina;
	celdaAbajo = getCelda(nCeldaAbajo);
	celda = getCelda(nCelda);
	if (nCeldaAbajo%getNumeroFilas() != 0){
		if(!celda->isVacia()){
			while (!celdaAbajo->getEstado() &&
					nCeldaAbajo%getNumeroFilas() != 0){
				nCeldaAbajo++;
				celdaAbajo = getCelda(nCeldaAbajo);
			}
			if (celdaAbajo->isVacia()){
				golosina = celda->getGolosina();
				while (golosina->getPosY() < celdaAbajo->getPosY()){
					golosina->setPosicion(golosina->getPosX(),
							golosina->getPosY() + CANTPIXELS);
					if (nCelda%getNumeroFilas() != 0){
						bajarGolosinaPixels(nCelda - 1, CANTPIXELS);
					}
					dibujar(false);
					SDL_Delay(10);
				}
				golosina->setPosicion(celdaAbajo->getPosX(),
											celdaAbajo->getPosY());
				celdaAbajo->setGolosina(golosina);
				celda->vaciar();
				if (nCelda != 0){
					bajarGolosina(nCelda-1);
				}else if ((nCelda + 1 ) != (getNumeroColumnas() *
						getNumeroFilas())){
					bajarGolosina(nCeldaAbajo);
				}
			}
		}else if (nCelda > 0){
			nCelda -= 1;
			bajarGolosina(nCelda);
		}
	}
}

void TableroSDL::reponerGolosina(Golosina* golosina, unsigned int col){
	CeldaSDL* celda;
	unsigned int nCel = (col)*(getNumeroFilas());
	celda = getCelda(nCel);
	golosina->setPosicion(celda->getPosX(), celda->getPosY());
	celda->setGolosina(golosina);
}

void TableroSDL::habilitarDibujarJugadas(){
	dibujarJugadas = true;
}

bool TableroSDL::getDibujarJugadas(){
	return dibujarJugadas;
}

void TableroSDL::bajarGolosinaPixels(unsigned int nCelda, int nPixels){
	CeldaSDL* celda;
	Golosina* golosina;
	celda = getCelda(nCelda);
	if(!celda->isVacia() && celda->getEstado()
			&& nCelda%getNumeroFilas() != 0){
		golosina = celda->getGolosina();
		golosina->setPosicion(golosina->getPosX(),
										golosina->getPosY() + nPixels);
	}
	if(nCelda%getNumeroFilas() != 0){
		bajarGolosinaPixels(nCelda - 1, nPixels);
	}
}


